/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

#include "PublicTimer.h"
#if USE_PUBLIC_TIMER
#include <sys/select.h>
#include <time.h>
#include <pthread.h>
#include "PublicThread.h"
using namespace std;
//////////////////////////public methods//////////////////////////
PublicTimer::PublicTimer():m_second(0){
	m_first=1;
}
PublicTimer::PublicTimer(long second):m_second(second){
}
PublicTimer::~PublicTimer(){
}
void PublicTimer::SetTimer(long second){
    m_second = second;
}
void PublicTimer::StartTimer(){
	if(m_fun==NULL)exit(-1);
    pthread_create(&thread_timer, NULL, OnTimer_stub, this);
	ThreadBindCPU(thread_timer,-1);
}
void PublicTimer::StopTimer(){
    pthread_cancel(thread_timer);
    pthread_join(thread_timer, NULL); //wait the thread stopped
}
void PublicTimer::SetTimerFun(TimerFun fun){
	m_fun=fun;
}
//////////////////////////private methods//////////////////////////
void PublicTimer::thread_proc(){
    while (true){
//		OnTimer();
		(*m_fun)(0);
        pthread_testcancel();
//只支持秒级		
		struct timeval tempval={0,0};
		struct timeval realtime={0,0};
		gettimeofday(&realtime,NULL);

		if(realtime.tv_usec==0){
			tempval.tv_sec = m_second-realtime.tv_sec%m_second;
			tempval.tv_usec = 1;
		}else{
			tempval.tv_sec = m_second-realtime.tv_sec%m_second-1;
			tempval.tv_usec = 1000000-realtime.tv_usec;
		}	
        select(0,NULL,NULL,NULL,&tempval);
    }
}

void PublicTimer::OnTimer(){
	if(m_fun){
		(*m_fun)(0);
	}
}
#endif